Revert the button state to !button_down, if we're missing the release
authorMatthias Clasen <mclasen@redhat.com>
Sun, 26 Sep 2004 05:47:11 +0000 (05:47 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Sun, 26 Sep 2004 05:47:11 +0000 (05:47 +0000)
2004-09-26  Matthias Clasen  <mclasen@redhat.com>

* gtk/gtkbutton.c: Revert the button state to !button_down,
if we're missing the release event due to grab shadowing
or insensitivation.

* gtk/gtkpathbar.c: Make the slider buttons scroll.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkbutton.c
gtk/gtkpathbar.c

index 810389c2a7d76f330401c97c80e5a834ca328985..d32a646c31826a0e5b5177705d7cf78e2662ce95 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2004-09-26  Matthias Clasen  <mclasen@redhat.com>
 
+       * gtk/gtkbutton.c: Revert the button state to !button_down,
+       if we're missing the release event due to grab shadowing
+       or insensitivation.
+
+       * gtk/gtkpathbar.c: Make the slider buttons scroll.
+
        * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): Remove 
        debug spew.
        (bookmarks_check_remove_sensitivity): Don't free an uninitialized
index 810389c2a7d76f330401c97c80e5a834ca328985..d32a646c31826a0e5b5177705d7cf78e2662ce95 100644 (file)
@@ -1,5 +1,11 @@
 2004-09-26  Matthias Clasen  <mclasen@redhat.com>
 
+       * gtk/gtkbutton.c: Revert the button state to !button_down,
+       if we're missing the release event due to grab shadowing
+       or insensitivation.
+
+       * gtk/gtkpathbar.c: Make the slider buttons scroll.
+
        * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): Remove 
        debug spew.
        (bookmarks_check_remove_sensitivity): Don't free an uninitialized
index 810389c2a7d76f330401c97c80e5a834ca328985..d32a646c31826a0e5b5177705d7cf78e2662ce95 100644 (file)
@@ -1,5 +1,11 @@
 2004-09-26  Matthias Clasen  <mclasen@redhat.com>
 
+       * gtk/gtkbutton.c: Revert the button state to !button_down,
+       if we're missing the release event due to grab shadowing
+       or insensitivation.
+
+       * gtk/gtkpathbar.c: Make the slider buttons scroll.
+
        * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): Remove 
        debug spew.
        (bookmarks_check_remove_sensitivity): Don't free an uninitialized
index 810389c2a7d76f330401c97c80e5a834ca328985..d32a646c31826a0e5b5177705d7cf78e2662ce95 100644 (file)
@@ -1,5 +1,11 @@
 2004-09-26  Matthias Clasen  <mclasen@redhat.com>
 
+       * gtk/gtkbutton.c: Revert the button state to !button_down,
+       if we're missing the release event due to grab shadowing
+       or insensitivation.
+
+       * gtk/gtkpathbar.c: Make the slider buttons scroll.
+
        * gtk/gtkfilechooserdefault.c (shortcuts_remove_rows): Remove 
        debug spew.
        (bookmarks_check_remove_sensitivity): Don't free an uninitialized
index 9e250d748f78a0f6f5d4a83c266ad5df109ab186..0153ec3cd1c3bcf8900ebf3c6fe233e0456a6f81 100644 (file)
@@ -125,10 +125,15 @@ static GType gtk_button_child_type    (GtkContainer     *container);
 static void gtk_button_finish_activate (GtkButton *button,
                                        gboolean   do_it);
 
-static GObject*        gtk_button_constructor     (GType                  type,
-                                           guint                  n_construct_properties,
-                                           GObjectConstructParam *construct_params);
+static GObject*        gtk_button_constructor (GType                  type,
+                                       guint                  n_construct_properties,
+                                       GObjectConstructParam *construct_params);
 static void gtk_button_construct_child (GtkButton             *button);
+static void gtk_button_state_changed   (GtkWidget             *widget,
+                                       GtkStateType           previous_state);
+static void gtk_button_grab_notify     (GtkWidget             *widget,
+                                       gboolean               was_grabbed);
+
 
 
 static GtkBinClass *parent_class = NULL;
@@ -196,6 +201,8 @@ gtk_button_class_init (GtkButtonClass *klass)
   widget_class->key_release_event = gtk_button_key_release;
   widget_class->enter_notify_event = gtk_button_enter_notify;
   widget_class->leave_notify_event = gtk_button_leave_notify;
+  widget_class->state_changed = gtk_button_state_changed;
+  widget_class->grab_notify = gtk_button_grab_notify;
 
   container_class->child_type = gtk_button_child_type;
   container_class->add = gtk_button_add;
@@ -1646,3 +1653,29 @@ gtk_button_screen_changed (GtkWidget *widget,
 
   show_image_change_notify (GTK_BUTTON (widget));
 }
+
+static void
+gtk_button_state_changed (GtkWidget    *widget,
+                          GtkStateType  previous_state)
+{
+  GtkButton *button = GTK_BUTTON (widget);
+
+  if (!GTK_WIDGET_IS_SENSITIVE (widget))
+    {
+      button->in_button = FALSE;
+      gtk_real_button_released (button);
+    }
+}
+
+static void
+gtk_button_grab_notify (GtkWidget *widget,
+                       gboolean   was_grabbed)
+{
+  GtkButton *button = GTK_BUTTON (widget);
+
+  if (!was_grabbed)
+    {
+      button->in_button = FALSE;
+      gtk_real_button_released (button);
+    }
+}
index 67ac552bd7e5bd0938cc8e8b830adda34c96107b..84e824bb2134fc2e9ac0ec7054fa3840e78ee831 100644 (file)
@@ -1,4 +1,4 @@
-/* gtkpathbar.h
+/* gtkpathbar.c
  * Copyright (C) 2004  Red Hat, Inc.,  Jonathan Blandford <jrb@gnome.org>
  *
  * This library is free software; you can redistribute it and/or
@@ -47,6 +47,9 @@ typedef enum {
 
 #define BUTTON_DATA(x) ((ButtonData *)(x))
 
+#define SCROLL_TIMEOUT           150
+#define INITIAL_SCROLL_TIMEOUT   300
+
 static guint path_bar_signals [LAST_SIGNAL] = { 0 };
 
 /* Icon size for if we can't get it from the theme */
@@ -88,6 +91,16 @@ static void gtk_path_bar_scroll_up                (GtkWidget        *button,
                                                   GtkPathBar       *path_bar);
 static void gtk_path_bar_scroll_down              (GtkWidget        *button,
                                                   GtkPathBar       *path_bar);
+static gboolean gtk_path_bar_slider_button_press  (GtkWidget        *widget,
+                                                  GdkEventButton   *event,
+                                                  GtkPathBar       *path_bar);
+static gboolean gtk_path_bar_slider_button_release(GtkWidget        *widget,
+                                                  GdkEventButton   *event,
+                                                  GtkPathBar       *path_bar);
+static void gtk_path_bar_grab_notify              (GtkWidget        *widget,
+                                                  gboolean          was_grabbed);
+static void gtk_path_bar_state_changed            (GtkWidget        *widget,
+                                                  GtkStateType      previous_state);
 static void gtk_path_bar_style_set                (GtkWidget        *widget,
                                                   GtkStyle         *previous_style);
 static void gtk_path_bar_screen_changed           (GtkWidget        *widget,
@@ -125,9 +138,14 @@ gtk_path_bar_init (GtkPathBar *path_bar)
   path_bar->up_slider_button = get_slider_button (path_bar, GTK_ARROW_LEFT);
   path_bar->down_slider_button = get_slider_button (path_bar, GTK_ARROW_RIGHT);
   path_bar->icon_size = FALLBACK_ICON_SIZE;
-
+  
   g_signal_connect (path_bar->up_slider_button, "clicked", G_CALLBACK (gtk_path_bar_scroll_up), path_bar);
   g_signal_connect (path_bar->down_slider_button, "clicked", G_CALLBACK (gtk_path_bar_scroll_down), path_bar);
+
+  g_signal_connect (path_bar->up_slider_button, "button_press_event", G_CALLBACK (gtk_path_bar_slider_button_press), path_bar);
+  g_signal_connect (path_bar->up_slider_button, "button_release_event", G_CALLBACK (gtk_path_bar_slider_button_release), path_bar);
+  g_signal_connect (path_bar->down_slider_button, "button_press_event", G_CALLBACK (gtk_path_bar_slider_button_press), path_bar);
+  g_signal_connect (path_bar->down_slider_button, "button_release_event", G_CALLBACK (gtk_path_bar_slider_button_release), path_bar);
 }
 
 static void
@@ -150,6 +168,8 @@ gtk_path_bar_class_init (GtkPathBarClass *path_bar_class)
   widget_class->size_allocate = gtk_path_bar_size_allocate;
   widget_class->style_set = gtk_path_bar_style_set;
   widget_class->screen_changed = gtk_path_bar_screen_changed;
+  widget_class->grab_notify = gtk_path_bar_grab_notify;
+  widget_class->state_changed = gtk_path_bar_state_changed;
 
   container_class->add = gtk_path_bar_add;
   container_class->forall = gtk_path_bar_forall;
@@ -589,7 +609,13 @@ gtk_path_bar_scroll_down (GtkWidget *button, GtkPathBar *path_bar)
   gint space_needed;
   gint border_width;
   GtkTextDirection direction;
-  
+
+  if (path_bar->ignore_click)
+    {
+      path_bar->ignore_click = FALSE;
+      return;   
+    }
+
   gtk_widget_queue_resize (GTK_WIDGET (path_bar));
 
   border_width = GTK_CONTAINER (path_bar)->border_width;
@@ -641,6 +667,12 @@ gtk_path_bar_scroll_up (GtkWidget *button, GtkPathBar *path_bar)
 {
   GList *list;
 
+  if (path_bar->ignore_click)
+    {
+      path_bar->ignore_click = FALSE;
+      return;   
+    }
+
   gtk_widget_queue_resize (GTK_WIDGET (path_bar));
 
   for (list = g_list_last (path_bar->button_list); list; list = list->prev)
@@ -653,6 +685,110 @@ gtk_path_bar_scroll_up (GtkWidget *button, GtkPathBar *path_bar)
     }
 }
 
+static gboolean
+gtk_path_bar_scroll_timeout (GtkPathBar *path_bar)
+{
+  gboolean retval = FALSE;
+
+  GDK_THREADS_ENTER ();
+
+  if (path_bar->timer)
+    {
+      if (GTK_WIDGET_HAS_FOCUS (path_bar->up_slider_button))
+       gtk_path_bar_scroll_up (path_bar->up_slider_button, path_bar);
+      else if (GTK_WIDGET_HAS_FOCUS (path_bar->down_slider_button))
+       gtk_path_bar_scroll_down (path_bar->down_slider_button, path_bar);
+
+      if (path_bar->need_timer) 
+       {
+         path_bar->need_timer = FALSE;
+
+         path_bar->timer = g_timeout_add (SCROLL_TIMEOUT,
+                                          (GSourceFunc)gtk_path_bar_scroll_timeout,
+                                          path_bar);
+         
+       }
+      else
+       retval = TRUE;
+      
+    }
+
+  GDK_THREADS_LEAVE ();
+
+  return retval;
+}
+
+static void 
+gtk_path_bar_stop_scrolling (GtkPathBar *path_bar)
+{
+  if (path_bar->timer)
+    {
+      g_source_remove (path_bar->timer);
+      path_bar->timer = 0;
+      path_bar->need_timer = FALSE;
+    }
+}
+
+static gboolean
+gtk_path_bar_slider_button_press (GtkWidget      *widget, 
+                                 GdkEventButton *event,
+                                 GtkPathBar     *path_bar)
+{
+  if (!GTK_WIDGET_HAS_FOCUS (widget))
+    gtk_widget_grab_focus (widget);
+
+  if (event->type != GDK_BUTTON_PRESS || event->button != 1)
+    return FALSE;
+
+  path_bar->ignore_click = FALSE;
+
+  if (widget == path_bar->up_slider_button)
+    gtk_path_bar_scroll_up (path_bar->up_slider_button, path_bar);
+  else if (widget == path_bar->down_slider_button)
+     gtk_path_bar_scroll_down (path_bar->down_slider_button, path_bar);
+
+  if (!path_bar->timer)
+    {
+      path_bar->need_timer = TRUE;
+      path_bar->timer = g_timeout_add (INITIAL_SCROLL_TIMEOUT,
+                                      (GSourceFunc)gtk_path_bar_scroll_timeout,
+                                      path_bar);
+    }
+
+  return FALSE;
+}
+
+static gboolean
+gtk_path_bar_slider_button_release (GtkWidget      *widget, 
+                                   GdkEventButton *event,
+                                   GtkPathBar     *path_bar)
+{
+  if (event->type != GDK_BUTTON_RELEASE)
+    return FALSE;
+
+  path_bar->ignore_click = TRUE;
+  gtk_path_bar_stop_scrolling (path_bar);
+
+  return FALSE;
+}
+
+static void
+gtk_path_bar_grab_notify (GtkWidget *widget,
+                         gboolean   was_grabbed)
+{
+  if (!was_grabbed)
+    gtk_path_bar_stop_scrolling (GTK_PATH_BAR (widget));
+}
+
+static void
+gtk_path_bar_state_changed (GtkWidget    *widget,
+                           GtkStateType  previous_state)
+{
+  if (!GTK_WIDGET_IS_SENSITIVE (widget)) 
+    gtk_path_bar_stop_scrolling (GTK_PATH_BAR (widget));
+}
+
+
 /* Changes the icons wherever it is needed */
 static void
 reload_icons (GtkPathBar *path_bar)
@@ -1029,6 +1165,13 @@ gtk_path_bar_check_parent_path (GtkPathBar         *path_bar,
                                                 BUTTON_DATA (list->data),
                                                 (list == current_path) ? TRUE : FALSE);
        }
+#if 1
+      if (!gtk_widget_get_child_visible (BUTTON_DATA (current_path->data)->button))
+       {
+         path_bar->first_scrolled_button = current_path;
+         gtk_widget_queue_resize (GTK_WIDGET (path_bar));
+       }
+#endif
       return TRUE;
     }
   return FALSE;